libxl: don't leak gc pointers to caller's structs; prevent double free
authorGianni Tedesco <gianni.tedesco@citrix.com>
Fri, 10 Sep 2010 17:49:00 +0000 (18:49 +0100)
committerGianni Tedesco <gianni.tedesco@citrix.com>
Fri, 10 Sep 2010 17:49:00 +0000 (18:49 +0100)
libxl_build_device_model uses a pointer in a caller supplied data
structure to synthesize a vif-name if one is not supplied. This is bad
juju because the caller may want to free this pointer but by the time it
get's a chance the gc has already done so. Switch to using a local
variable for this pointer and avoid a double-free in the domain create
path.

Gianni Tedesco <gianni.tedesco@citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
tools/libxl/libxl.c

index d5e44e6a86a3b50fff80cfa0c5bfc4cffc5f3bf3..5e5c48234728ae1568e00b3fc431b99fd5977ba5 100644 (file)
@@ -1190,14 +1190,17 @@ static char ** libxl_build_device_model_args_old(libxl__gc *gc,
                 char *smac = libxl__sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x",
                                            vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
                                            vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
+                char *ifname;
                 if (!vifs[i].ifname)
-                    vifs[i].ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
+                    ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
+                else
+                    ifname = vifs[i].ifname;
                 flexarray_set(dm_args, num++, "-net");
                 flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
                             vifs[i].devid, smac, vifs[i].model));
                 flexarray_set(dm_args, num++, "-net");
                 flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,bridge=%s,script=no",
-                            vifs[i].devid, vifs[i].ifname, vifs[i].bridge));
+                            vifs[i].devid, ifname, vifs[i].bridge));
                 ioemu_vifs++;
             }
         }